<?php
/**
 * 基类
 *
 * @dat
 */

namespace app\api\controller;
use think\Controller;
use think\Response;
use think\exception\HttpResponseException;
use think\Db;

class Base extends Controller
{
    protected $uid;
    protected $token;
    protected $app_version;
    protected $app_platform;
    
    protected $write_log = true;// true 开启日志，false 关闭日志

    public function initialize()
    {
        $this->app_version = input('app_version', 0, 'intval');// 版本号
        $this->app_platform = input('app_platform', 1, 'intval');// 1 IOS、2 Android

        if (!isset($_GET['is_check']) || $_GET['is_check']!='false') {
            $this->isLogined();
        } else {
            // 测试也可以指定某人
            $uid = input('uid', 0, 'intval');
            $uid && $this->uid = $uid;
            $token = input('token');
            $this->token = $token;
        }
    }

    private  function isLogined()
    {
        $module     = strtolower(request()->module());
        $controller = strtolower(request()->controller());
        $action     = strtolower(request()->action());
        $url        = $module."/".$controller."/".$action;
        $uid = input('uid');
        $token = input('token');

        if(!in_array($url, config('no_login_urls'))){
            if(empty($uid) || empty($token)) {
                $this->ajaxReturn(-1, '缺少基本参数uid或token');
            }

            if(!$this->verify($uid,$token)){
                $this->ajaxReturn(-100, '未登录或登录已过期，请重新登录');
            }

            $this->uid = $uid;
            $this->token = $token;
        }
    }

    private function verify($uid,$token)
    {
        if($uid && $token) {
            $de_token = cache($this->tokenKey($uid));
            if($de_token == $token) {
                return true;
            }
        }

        return false;
    }

    /**
     * 检测是否有人已经登录此账号，不允许多人同时登录同一账号
     * @param  [string] $uuid [用户uuid]
     * @return [boolean]      true 有人登录，false 还没有其他人登录
     */
    protected function checkOtherLogin($uid)
    {
        $de_token = cache($this->tokenKey($uid));
        if (empty($de_token)) {
            return false;
        } else {
            return $de_token;
        }
    }

    protected function createToken($uid)
    {
        if (function_exists('openssl_random_pseudo_bytes')) {
            $strong = true;
            $token =  sha1(openssl_random_pseudo_bytes(16,$strong) . $uid);
        }else {
            $token = base64_encode(substr(md5(microtime()),0,8).base64_encode($uid).substr(md5($uid),10,4));
        }

        cache($this->tokenKey($uid),$token, 7*86400);// 登录7天有效

        return $token;
    }

    protected function delToken($uid) {
        $token = input('param.token');// 可能被强制退出，所以不能使用this->token
        // 为当前登录的时候才删除
        if ($this->verify($uid, $token)) {
            cache($this->tokenKey($uid),null,1);
        }
    }
    
    private function tokenKey($uid) {
        return config('XF_TOKEN_KEY').$uid;
    }

    /**
     * 统一格式返回 强制
     * @Author zhibin
     * @Date   2020-06-19
     * @param  integer    $code   [description]
     * @param  string     $msg    [description]
     * @param  array      $data   [description]
     * @param  string     $type   [description]
     * @param  array      $header [description]
     * @return [type]             [description]
     */
    protected function ajaxReturn($code = 0, $msg = '', $data=[], $type = 'json', array $header = [])
    {
        $result = [
            'status' => $code,
            'msg'  => $msg,
            'data' => $data,
        ];
        $type     = $type ?: $this->getResponseType();
        $response = Response::create($result, $type)->header($header);
        throw new HttpResponseException($response);
    }
    
    /**
     * 写请求和响应日志, 根据开关 
     * @param int $operator 操作类型，自定义，默认系统操作
     * @param Array $return 返回的数组
     */
    protected function api_write_log($operator=0, $return = [])
    {
        if (!$this->write_log) {
            //关闭日志，直接跳过
            return true;
        }
        $module     = strtolower(request()->module());
        $controller = strtolower(request()->controller());
        $action     = strtolower(request()->action());
        
        // 记录请求日志，保存请求的参数
        $params = input('param.');
        $client_ip = request()->ip();
        $start_time = time();
        $end_time = $start_time;
        $ext_return = [
            'ext_start_time' => $start_time,
            'ext_end_time' => $end_time,
            'ip' => $client_ip,
        ];
        $return_data = json_encode(array_merge($return, $ext_return));
        $log_data = [
            'login_uid' => $this->uid,
            'operator' => $operator,
            'module' => $module,
            'controller' => $controller,
            'action' => $action,
            'app_version' => $this->app_version,
            'app_platform' => $this->app_platform,
            'requet_params' => json_encode($params),
            'create_time' => $start_time,
            'return_data' => $return_data,
        ];
        //var_dump($log_data);
        $result = Db::name('api_request_log')->insert($log_data);
        //var_dump(Db::name('api_request_log')->getLastSql());
    }
}
